package com.jari.lg.service.analysis.vehicle;

import com.jari.lg.domain.*;
import com.jari.lg.mapper.*;
import com.jari.lg.utils.BaseData;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * author ge
 * description 编写车辆时空分析一些数据生成程序
 */
@Service
public class VehicleService {

    @Autowired
    private WholeMileDayMapper wholeMileDayMapper;

    @Autowired
    private WholeMileMonthMapper wholeMileMonthMapper;

    @Autowired
    private VehicleCpTypeDayMapper vehicleCpTypeDayMapper;

    @Autowired
    private OdDayMapper odDayMapper;

    @Autowired
    private SpecialCarAreaInfoMapper specialCarAreaInfoMapper;

    /**
     * 每天23点设置一天OD数据
     *
     * @param current
     */
    //@Scheduled(cron = "* * 23 * * ?")
    public void setOdDay(Date current, Date tomorrow) {
        //每天生成10条OD 数据
        List<DevBase> checkpointList = BaseData.checkpointList;
        List<OdDay> result = new ArrayList<>();
        //随机从卡口中获取10对卡口对应下标
        int length = checkpointList.size();
        for (int i = 0; i < 10; i++) {
            OdDay entity = new OdDay();
            List<DevBase> startEndCheckpoint = getStartEndCheckpoint(checkpointList);
            DevBase start = startEndCheckpoint.get(0);
            DevBase end = startEndCheckpoint.get(1);
            //每天区域流动车辆数量设置为1000-20000之间
            int carNum = (int) (Math.random() * 19001 + 1000);
            entity.setStartdatetime(current);
            entity.setEnddatetime(tomorrow);
            entity.setStartcheckpointcode(start.getDevicecode());
            entity.setStartcheckpointname(start.getDevicename());
            entity.setEndcheckpointcode(end.getDevicecode());
            entity.setEndcheckpointname(end.getDevicename());
            entity.setCarnum(carNum);

            result.add(entity);
        }
        odDayMapper.insertBatch(result);
    }

    public List<DevBase> getStartEndCheckpoint(List<DevBase> checkpointList) {
        List<DevBase> result = new ArrayList<>();
        int length = checkpointList.size();
        int startNum = (int) (Math.random() * length);
        int endNum = (int) (Math.random() * length);
        while (startNum == endNum) {
            endNum = (int) (Math.random() * length);
        }
        result.add(checkpointList.get(startNum));
        result.add(checkpointList.get(endNum));

        return result;
    }

    /**
     * 每天23点设置不同类型车辆出现时间段表
     */
    //@Scheduled(cron = "* * 23 * * ?")
    public void setSpecialCarAreaInfo(Date current) {
        //对于每一个卡口，随机选取若干车辆类型，随机设置若干开始结束时间
        List<SysDictData> carTypeList = BaseData.carTypeList;
        List<DevBase> checkpointList = BaseData.checkpointList;
        List<SpecialCarAreaInfo> result = new ArrayList<>();
        int checkPointLength = checkpointList.size();

        for (int i = 0; i < checkPointLength; i++) {
            SpecialCarAreaInfo specialCarAreaInfo = new SpecialCarAreaInfo();
            DevBase devBase = checkpointList.get(i);
            specialCarAreaInfo.setCheckpointcode(devBase.getDevicecode());
            specialCarAreaInfo.setCheckpointname(devBase.getDevicename());
            specialCarAreaInfo.setDatetime(current);
            //每种类型车数量在300-2000之间
            specialCarAreaInfo.setDistrictpassingcarnum(300 + (int) (Math.random() * 1701));
            //0 - （length-1）
            int randomNum = (int) (Math.random() * (carTypeList.size()));
            specialCarAreaInfo.setCartype(carTypeList.get(randomNum).getDictlabel());
            //对于时间段，设置三个时间段，对应到哪个时间段就进行时间段设置
            int timeNum = 1 + (int) (Math.random() * 3);
            switch (timeNum) {
                case 1:
                    specialCarAreaInfo.setStartdatetime(getSpecialTime(current, 6));//当天6:00-11:00
                    specialCarAreaInfo.setEnddatetime(getSpecialTime(current, 11));
                    break;
                case 2:
                    specialCarAreaInfo.setStartdatetime(getSpecialTime(current, 14));//当天14:00-18:00
                    specialCarAreaInfo.setEnddatetime(getSpecialTime(current, 18));
                    break;
                case 3:
                    specialCarAreaInfo.setStartdatetime(getSpecialTime(current, 20));//当天20:00-23:00
                    specialCarAreaInfo.setEnddatetime(getSpecialTime(current, 23));
                    break;
                default:
                    break;
            }
            result.add(specialCarAreaInfo);
        }
        specialCarAreaInfoMapper.insertBatch(result);

    }

    //获取某一天的某一时间段
    public Date getSpecialTime(Date current, int hourNum) {
        Calendar time = Calendar.getInstance();
        time.setTime(current);
        time.set(Calendar.HOUR_OF_DAY, hourNum);
        time.set(Calendar.MINUTE, 00);
        time.set(Calendar.SECOND, 00);
        time.set(Calendar.MILLISECOND, 000);
        return time.getTime();
    }

    /**
     * 每天晚上23点进行一天所有车辆行驶里程数目数据入库
     */
    //@Scheduled(cron = "* * 23 * * ?")
    public void setWholeMileDayInfo(Date currentDate) {
        //获取所有carType，对于每一种类型，设置对应的行驶总里程数
        //String[] carType = BaseData.carType;
        List<SysDictData> carTypeList = BaseData.carTypeList;
        int length = carTypeList.size();
        for (int i = 0; i < length; i++) {
            WholeMileDay wholeMileDay = new WholeMileDay();
            String carTypeS = carTypeList.get(i).getDictlabel();
            //对于特殊车辆，没有那么多，所以需要特别设置一下，一天的数量在500-3000辆之间,一辆车一天大约行驶3000米-20000米之间
            if (StringUtils.equals(carTypeS, "特殊车辆")) {
                wholeMileDay.setCarwholenumber((int) (500 + (Math.random() * 2501)));
            } else if (StringUtils.equals(carTypeS, "营运车辆")) {
                //每天车辆数在20000 - 50000
                wholeMileDay.setCarwholenumber((int) (20000 + (Math.random() * 30001)));
            } else {
                //其他类型车辆一天数量在100000-200000之间
                wholeMileDay.setCarwholenumber((int) (100000 + (Math.random() * 100001)));
            }
            wholeMileDay.setCartype(carTypeS);
            wholeMileDay.setWholemileageday((int) (wholeMileDay.getCarwholenumber() * (3000 + (Math.random() * 17001))));
            wholeMileDay.setDatetime(currentDate);
            //插入数据库中
            wholeMileDayMapper.insert(wholeMileDay);
        }
    }

    /**
     * 每月最后一天的23.30进行月车辆行驶里程数据入库
     */
    //@Scheduled(cron = "* * 23 L * ?")
    public void setWholeMileMonthInfo(Date current) {
        //获取所有carType，对于每一种类型，设置对应的行驶总里程数
        List<SysDictData> carTypeList = BaseData.carTypeList;
        int length = carTypeList.size();
        for (int i = 0; i < length; i++) {
            WholeMileMonth wholeMileMonth = new WholeMileMonth();
            String carTypeS = carTypeList.get(i).getDictlabel();
            //对于特殊车辆，没有那么多，所以需要特别设置一下，一个月的数量在20000-100000辆之间,一辆车一天大约行驶3000米-20000米之间
            if (StringUtils.equals(carTypeS, "特殊车辆")) {
                wholeMileMonth.setCarwholenumber((int) (20000 + (Math.random() * 80001)));
            } else if (StringUtils.equals(carTypeS, "营运车辆")) {
                //每天车辆数在60万 - 150万
                wholeMileMonth.setCarwholenumber((int) (600000 + (Math.random() * 900001)));
            } else {
                //其他类型车辆一个月在300万-620万
                wholeMileMonth.setCarwholenumber((int) (3000000 + (Math.random() * 3200001)));
            }
            wholeMileMonth.setCartype(carTypeS);
            int originMile = (wholeMileMonth.getCarwholenumber() / 10000) * (int) (3000 + (Math.random() * 17001)) * 30;
            wholeMileMonth.setWholemileagemonth(originMile);//数值太大所以设置单位是“十万”
            wholeMileMonth.setDatetime(current);
            //插入数据库中
            wholeMileMonthMapper.insert(wholeMileMonth);
        }
    }

    /**
     * 每天22 点生成当天本地外地及各省车辆占比情况表数据
     */
    //@Scheduled(cron = "* * 22 * * ?")
    public void setVehicleCpTypeDayInfo(Date current) {
        //获取所有卡口数据，对于每一个卡口进行本地外地车数量生成
        List<DevBase> checkpointList = BaseData.checkpointList;
        List<VehicleCpTypeDay> resultList = new ArrayList<>();
        int length = checkpointList.size();
        for (int i = 0; i < length; i++) {
            VehicleCpTypeDay vehicleCpTypeDay = new VehicleCpTypeDay();
            DevBase devBase = checkpointList.get(i);
            vehicleCpTypeDay.setCheckpointcode(devBase.getDevicecode());
            vehicleCpTypeDay.setCheckpointname(devBase.getDevicename());
            vehicleCpTypeDay.setDate(current);
            //设置每天一个卡口的本地车数量在300-5000辆，外地车在100-3000辆之间
            vehicleCpTypeDay.setLocalcarnum(300 + (int) (Math.random() * 4701));
            vehicleCpTypeDay.setNolocalcarnum(100 + (int) (Math.random() * 2901));
            vehicleCpTypeDay.setProvinceset(getProvinceSet(vehicleCpTypeDay.getLocalcarnum(), vehicleCpTypeDay.getNolocalcarnum()));

            resultList.add(vehicleCpTypeDay);
        }
        vehicleCpTypeDayMapper.insertBatch(resultList);

    }

    public String getProvinceSet(int localNum, int noLocalNum) {
        //一共34个省，生成34个数据，总数加起来为外地车数量总和
        int[] store = new int[34];
        StringBuffer stringBuffer = new StringBuffer();
        int sum = 0;
        //对于特定的几个先进行设置
        store[0] = store[2] = store[12] = store[13] = store[14] = store[16] = store[18] = (int) (0.05 * noLocalNum);
        store[17] = (int) (0.2 * noLocalNum);
        store[22] = (int) (0.15 * noLocalNum);
        store[1] = localNum;
        sum += (int) (0.7 * noLocalNum);
        int i = 3;
        while (i < 34) {
            if (i == 12 || i == 13 || i == 14 || i == 16 || i == 17 || i == 18 || i == 22) {
                i++;
                continue;
            }
            int val = (int) (Math.random() * (noLocalNum - sum + 1));
            if (val < 0) val = 0;
            store[i] = val;
            sum += val;
            i++;
        }

        for (int j = 0; j < 34; j++) {
            if (j == 33) {
                stringBuffer.append(store[j]);
                break;
            }
            stringBuffer.append(store[j] + ",");
        }

        return stringBuffer.toString();
    }

}
